﻿using System;
using System.Collections.Generic;

namespace BaseUtil
{
    public static class H3dBitConverter
    {
        public static byte[] bool_byte = new byte[1];
        public static byte[] short_byte = new byte[2];
        public static byte[] int_byte = new byte[4];
        public static byte[] long_byte = new byte[8];


        public static byte[] GetBytes(bool value)
        {
            if(value)
            {
                bool_byte[0]=(byte)1;
            }
            else
            {
                bool_byte[0] = (byte)0;
            }
            return bool_byte;
        }

        public static byte[] GetBytes(char value)
        {
            return GetBytes((short)value);
        }

        public static unsafe byte[] GetBytes(double value)
        {
            return GetBytes(*((long*)&value));
        }

        public static unsafe byte[] GetBytes(short value)
        {
            fixed (byte* numRef = short_byte)
            {
                *((short*)numRef) = value;
            }
            return short_byte;
        }

        public static unsafe byte[] GetBytes(int value)
        {
            fixed (byte* numRef = int_byte)
            {
                *((int*)numRef) = value;
            }
            return int_byte;
        }

        public static unsafe byte[] GetBytes(long value)
        {
            fixed (byte* numRef = long_byte)
            {
                *((long*)numRef) = value;
            }
            return long_byte;
        }

        public static unsafe byte[] GetBytes(float value)
        {
            return GetBytes(*((int*)&value));
        }

        public static byte[] GetBytes(ushort value)
        {
            return GetBytes((short)value);
        }

        public static byte[] GetBytes(uint value)
        {
            return GetBytes((int)value);
        }

        public static byte[] GetBytes(ulong value)
        {
            return GetBytes((long)value);
        }

       
    }
    public class NetOutStream
    {
        public NetOutStream()
        {
            
        }
        public NetOutStream(NetBuffer buffer)
        {
            m_buffer = buffer;
        }
        public void SetBuffer(NetBuffer buffer) { m_buffer=buffer; }
        public NetBuffer GetBuffer() { return m_buffer; }
        public int Offset { get { return m_offset; } }
        public void Seek(int offset) { m_offset = offset; }
        public void Write(bool val)
        {
            this.m_buffer.ExpandTo(m_offset + 1);
            byte[] array = H3dBitConverter.GetBytes(val);
            
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 1;
        }

        public void Write(double val)
        {
            this.m_buffer.ExpandTo(m_offset + 8);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 8;
        }

        public void Write(short val)
        {
            this.m_buffer.ExpandTo(m_offset + 2);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 2;
        }

        public void Write(ushort val)
        {
            this.m_buffer.ExpandTo(m_offset + 2);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 2;
        }

        public void Write(int val)
        {
            this.m_buffer.ExpandTo(m_offset + 4);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 4;
        }

        public void Write(uint val)
        {
            this.m_buffer.ExpandTo(m_offset + 4);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 4;
        }

        public void Write(long val)
        {
            this.m_buffer.ExpandTo(m_offset + 8);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 8;
        }

        public void Write(ulong val)
        {
            this.m_buffer.ExpandTo(m_offset + 8);
            byte[] array = H3dBitConverter.GetBytes(val);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += 8;
        }

        public void Write(byte val)
        {
            this.m_buffer.ExpandTo(m_offset + 1);
            m_buffer.buffer[m_offset] = val;
            m_offset += 1;
        }

        public void Write(sbyte val)
        {
            Write((byte)val);
        }

        public void Write(float val)
        {
            byte[] array = H3dBitConverter.GetBytes(val);
            this.m_buffer.ExpandTo(m_offset + array.Length);
            array.CopyTo(m_buffer.buffer, m_offset);
            m_offset += array.Length;
        }

        public void Write(string val, bool write_lenth = true)
        {
            //take care the encoding
            byte[] strval = System.Text.Encoding.UTF8.GetBytes(val);

            if (write_lenth)
            {
                this.Write(strval.Length);
            }

            this.m_buffer.ExpandTo(m_offset + strval.Length);

            strval.CopyTo(m_buffer.buffer, m_offset);
            m_offset += strval.Length;

            byte eos = 0;
            this.Write(eos);
        }

        public void Write(byte[] bytearray, bool write_lenth = true)
        {
            int length = bytearray.Length;

            if (write_lenth)
            {
                this.Write(length);
            }

            this.m_buffer.ExpandTo(m_offset + length);
            System.Array.Copy(bytearray, 0, m_buffer.buffer, m_offset, length);
            m_offset += length;
        }

        public void Write(NetBuffer buffer, bool write_lenth = true)
        {
            int length = buffer.length;

            if (write_lenth)
            {
                this.Write(length);
            }

            this.m_buffer.ExpandTo(m_offset + length);
            System.Array.Copy(buffer.buffer, 0, m_buffer.buffer, m_offset, length);
            m_offset += length;
        }

        private NetBuffer m_buffer;
        private int m_offset = 0;
    }
}
